home *** CD-ROM | disk | FTP | other *** search
- Path: wuarchive!swbatl!texbell!cs.utexas.edu!usc!elroy.jpl.nasa.gov!ames!xanth!cs.odu.edu!Amiga-Request
- From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
- Newsgroups: comp.sources.amiga
- Subject: v90i177: pdmake - maintain program groups, Part01/02
- Message-ID: <12706@xanth.cs.odu.edu>
- Date: 4 Jun 90 00:20:55 GMT
- Sender: tadguy@cs.odu.edu
- Reply-To: huver@amgraf.uucp
- Lines: 1999
- Approved: tadguy@cs.odu.edu (Tad Guy)
- X-Mail-Submissions-To: Amiga@cs.odu.edu
- X-Post-Discussions-To: comp.sys.amiga
-
- Submitted-by: huver@amgraf.uucp
- Posting-number: Volume 90, Issue 177
- Archive-name: unix/pdmake/part01
-
- I took the PDmake that Steve Walton ported to Amiga, and enhanced it a bit.
- Many attempts were made to contact Steve, but all failed (no mail bounce,
- absolutely nothing came back from him). So here it is, the complete thing.
- Note there was no version number at all in the PDmake distribution. If this
- is your first time seeing such buzzword as "PDmake", you should read the
- fles README, README.amiga first.
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 2)."
- # Contents: Changes.new README README.amiga an assign_macro.c check.c
- # h.h input.c macro.c main.c make.n makefile reader.c
- # Wrapped by tadguy@xanth on Sun Jun 3 20:20:41 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Changes.new' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Changes.new'\"
- else
- echo shar: Extracting \"'Changes.new'\" \(3328 characters\)
- sed "s/^X//" >'Changes.new' <<'END_OF_FILE'
- XApril 18, 1990
- X--huver hu ...!uunet!amgraf!huver -or- huver%amgraf@uunet.uu.net
- X
- X
- XI took the PDmake that Steve Walton ported to Amiga, and enhanced it a bit.
- XMany attempts were made to contact Steve, but all failed (no mail bounce,
- Xabsolutely nothing came back from him). So here it is, the complete thing.
- XNote there was no version number at all in the PDmake distribution. If this
- Xis your first time seeing such buzzword as "PDmake", you should read the
- Xfles README, README.amiga first, and then come back here.
- X
- XMy changes include:
- X
- X * Define suffixes .asm, .a, .s to all be assembler source files.
- X
- X * Added macros LD, LDFLAGS and LDLIBS so a linker can be invoked. For
- X Manx compiler system:
- X
- X LD = ln # linker program name
- X LDFLAGS =
- X LDLIBS = -lc # link with c.lib library
- X
- X * Add internal suffix .~ to generate an executable from a found source
- X file. The match order looks for assembler suffixes before .c suffix.
- X
- X * Run without a makefile present; i.e. a command line:
- X
- X make "CCFLGS=+L" foo
- X
- X runs the following actions (with Manx 3.6a):
- X
- X cc +L foo.c
- X ln -o foo foo.o -lc
- X
- X if foo.c is found in the current directory (note: the "-o" in linker
- X command above is not LDFLAGS, it comes from built-in rules; see rules.c).
- X This type of operation works only as indicated above (one source file
- X that is self-contained). Not a big deal, but it lets you get your simple
- X stand-alone tester made without overworking your fingers.
- X
- X * Instead of stopping at a target that Make doesn't know how to make, it
- X now issues an error message and continues on. So:
- X
- X make "CCFLAGS=+L" foo bar
- X
- X make: Don't know how to make foo.
- X
- X cc +L bar.c
- X ln -o bar bar.o -lc
- X
- X would still make "bar" in the event that no foo.* is found.
- X
- X * Corrected errors in handling '#' comment marker in the makefile. Such
- X comment mark can appear anywhere, from it to the first end-of-line is
- X all skipped. Likewise, there was problem in the backslash continuation
- X handling. The Makefile included with this distribution contains comment
- X lines placed on purpose, to illustrate what I mean here.
- X
- X * Added "-?" option to list all options.
- X
- XOtherwise, the original features Steve Walton put in are left intact.
- XAs far as I can tell, nothing should break under Manx 5.0 compiler.
- X
- X
- XMissing "feaures":
- X
- X 1. This Make definitely has no such concept as "being run from WB".
- X
- X 2. It cannot call itself to travel down a directory tree (no MAKE macro
- X and certainly no MFLAGS environmental variable).
- X
- X 3. It does not support object libraries.
- X
- XNotes to those of you who do not use Manx compiler:
- X
- X This make was written to use MANX's fexec() call to invoke commands (and
- X get their exit status back). I have no idea how other compilers do this.
- X
- X To take advantage of the source-to-executable action, you need to have
- X at least LD macro defined in "rules.c" (toward the end) -- having LDFLAGS
- X and LDLIBS defined wouldn't hurt, but may prove to be inconvenient. Edit
- X rules.c, go to the end and back up to where "#ifdef amiga" is at. Look for
- X things that I did (they are marked by comments with "--hu"), use them as
- X templates to set up command rules for make to call your compiler/linker.
- X
- X
- XYour comments are welcome, but don't expect me to be your Amiga PDmake
- Xsupport, though.
- END_OF_FILE
- if test 3328 -ne `wc -c <'Changes.new'`; then
- echo shar: \"'Changes.new'\" unpacked with wrong size!
- fi
- # end of 'Changes.new'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(1803 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XFollowing is a repost of the public domain 'make' that I posted
- Xto net.sources a couple of months ago. I have fixed a few bugs, and
- Xadded some more features, and the resulting changes amounted to
- Xabout as much text as the whole program (hence the repost).
- X
- XFor those that missed the net.sources posting, this is a public domain
- Xre-implementation of the UNIX make program. There is no manual included;
- Xfor documentation, refer to a UNIX manual, or the source.
- X
- XHere is a list of the changes made:
- X
- Xi) If '-' (ignore) or '@' (silent) where used at the start
- X of a command, their effect was not turned off for the following
- X commands.
- Xii) A special target (.SUFFIXES, .PRECIOUS) or a rule (.c.o, .a.o),
- X if first in the file would be taken as the default target.
- X This resulted in error messages like "Don't know how to
- X make .c", because things like .SUFFIXES were being made.
- X This was further complicated by ---
- Xiii) Special target lines with no dependents (ie. .SUFFIXES:\n)
- X were not clearing out the existing dependents like
- X they should.
- Xiv) Default rules could not be redefined because of the error
- X checking for commands being defined twice. Now you are
- X allowed to define a target beinging with '.', having
- X no dependents with commands.
- Xv) The -q option didn't do the time comparison correctly,
- X or clear the variable used to keep track of this. Thus
- X it didn't work very well.
- Xvi) The syntax ${..} for macro's supported by UNIX make was
- X not supported.
- Xvii) There wuz a couple of spelling errors.
- Xviii) When make checked for implicit rules on targets without
- X a suffix, there were problems. (Note: The ~ feature of
- X UNIX make wasn't and still isn't supported)
- Xix) The -n option did not print @ lines like it was supposed to.
- Xx) :: added. (See UNIX manual)
- Xxi) $? added. (see UNIX manual)
- END_OF_FILE
- if test 1803 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'README.amiga' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README.amiga'\"
- else
- echo shar: Extracting \"'README.amiga'\" \(4397 characters\)
- sed "s/^X//" >'README.amiga' <<'END_OF_FILE'
- XThis program is the public domain Make program which appeared on
- Xmod.sources, Volume 7, number 91. I have ported it to the Amiga under
- XManx Aztec C version 3.40a. This short document assumes you know
- XMake, and simply points out the Amiga specific features of the
- Xprogram. The supported switches are listed in the comment block at
- Xthe beginning of module main.c. I offer no apologies for the fact that
- XI ran the code through "indent -i4 -nfc1" on the 4.3BSD system at work
- Xbefore I started working on it.
- X The program has been compiled under Manx Aztec C Version 3.40.
- XIt uses Manx's fexecv() function to execute commands and get
- Xtheir return value, and the Manx dos_packet() function to send an
- XAmigaDOS packet to the file system for touch'ing purposes. Lattice
- Xrecompilers need to change these (at least). Peculiar features
- Xof the Amiga version are:
- X
- X(1) The Amiga-specific sections of the code are #ifdef'd on the symbol
- X amiga (note the lower case). I endorse Fred Fish's effort to
- X have system and compiler-supplied #define's in lower case to
- X ensure no collisions with user-supplied ones.
- X(2) The file rules.c, routine makerules(), contains the definitions of
- X the default built-in rules. For the Amiga, these are equivalent to
- X the Makefile:
- X
- X CC = cc
- X CFLAGS =
- X AS = as
- X AFLAGS =
- X
- X .c.o:
- X $(CC) $(CFLAGS) $<
- X .s.o:
- X $(AS) $(AFLAGS) -o $@ $<
- X
- X (indented for clarity only). Thus, one could conceivably do:
- X make CC=lc CFLAGS= AS=asm
- X to run this make under Lattice C.
- X(3) If the file S:builtins.make exists, its contents are read in
- X instead of the built-in rules defined in makerules(). Thus, you
- X can use different default rules on different disks and change
- X the default rules without recompiling make.
- X(4) A Control-D typed during execution of a command by make will cause
- X an abort with exit status 1 AFTER the completion of that command.
- X Control-C is an immediate abort, as you might expect.
- X(5) Not really Amiga specific, but worth mentioning, is that characters
- X special both to the local operating system (such as : in AmigaDOS) and
- X to make may be used in the makefile by preceding them with \
- X to temporarily override their special meaning. For example, to tell
- X make that RAM:foo depends on AC:foo.c, write:
- X
- X RAM\:foo : AC\:foo.c
- X
- X(6) The Aztec fexecv() function, which is used by make to execute its
- X commands, only works on programs in directories stored along the
- X AmigaDOS PATH, so make sure your PATH includes the appropriate
- X directories.
- X
- X Finally, I added one new feature in the non-machine-specific code:
- Xthe name of the makefile can be a single dash "-", in which case a
- Xmakefile is read from the standard input.
- X About the only feature of "real" make missing here is the
- Xsemicolon construct which allows a pair of lines such as the .c.o:
- Xrule and command above to be written as one line, viz:
- X .c.o: ; $(CC) $(CFLAGS) $<
- X
- XEnjoy! Bug reports in the Amiga-specific stuff should be directed to
- Xme; others should go to caret@fairlight.OZ, the author of the rest of it.
- XBy the way, this code is superior to the Manx-supplied make--more switches
- Xand a better parser; in fact, this make will handle the Makefile for
- XMicroGnuEmacs while Manx make chokes on the ln command.
- X
- X Steve Walton
- X ametek!walton@csvax.caltech.edu (ARPA)
- X WALTON@CALTECH (BITNET)
- X ...!ucbvax!sun!megatest!ametek!walton
- X
- XSome notes by Olaf Seibert, KosmoSoft:
- X
- XI adapted this version of make to PDC, and enhanced it a little. In
- Xparticular, if a line end with a backslash, the following newline and
- Xleading white space of the next line are now ignored. Previously, the
- Xnewline was merely turned into a space. Also, comparison of filenames now
- Xis case-insignificant. Makefiles need not be internally consistent in the
- Xcase of filenames. Also, the builtin rules are slightly different, for use
- Xwith PDC.
- X
- X CC = ccx -c
- X CFLAGS =
- X AS = ccx -c
- X AFLAGS =
- X
- X .c.o:
- X $(CC) $(CFLAGS) $<
- X .s.o:
- X $(AS) $(AFLAGS) $<
- X
- X /*OIS*0.80*/
- X
- XI took out the \: feature, which worked only in target names, and not in
- Xprerequisite files. Instead, I added a more rational interpretation of
- Xcolons. There is now at most one colon possible in a target name, which may
- Xnot contain any spaces.
- X
- XI incorporared a few bug fixes relating to $< and $*, from the minix newsgroup.
- XI added a new feature: the .PATH special target. See manual.
- X
- END_OF_FILE
- if test 4397 -ne `wc -c <'README.amiga'`; then
- echo shar: \"'README.amiga'\" unpacked with wrong size!
- fi
- # end of 'README.amiga'
- fi
- if test -f 'an' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'an'\"
- else
- echo shar: Extracting \"'an'\" \(2210 characters\)
- sed "s/^X//" >'an' <<'END_OF_FILE'
- X.*
- X.* Macro package for NRO in KosmoSoft version
- X.*
- X.nr h 5 @" header indent
- X.nr i 10 @" normal text indent
- X.nr s @ni-@nh @" section heading indent (to the LEFT)
- X.*
- X.de TH
- X.in @nh;.rm 80-@nh;.he |$0($1)|$2|$0($1)|
- X.fo |$3|-#-|$4|
- X.in @ni;.rm 80-@ni
- X.ta +0 +5
- X.en
- X.* Paragraph
- X.de PP
- X.sp 1;.ne 2;.ti +5
- X.en
- X.* Bulleted Paragraph. Needs .RE after last para.
- X.* Must be last on line. Relies on first tab stop.
- X.de BP
- X.br;.in @ni+5;.ti -3;o@t@@
- X.en
- X.* Section Heading
- X.de SH
- X.sp 1;.ne 3;.ti -@@ns;.bo "$0 $1 $2 $3 $4 $6 $6 $7 $8 $9
- X.br
- X.en
- X.* SubSection
- X.de SS
- X.br;.ne 2;.ti -@@ns+1/2;$0 $1 $2 $3 $4 $5 $6 $7 $8 $9
- X.br
- X.en
- X.* Relative indent Start
- X.de RS
- X.in +0$0
- X.en
- X.* Relative indent End
- X.de RE
- X.in @ni
- X.en
- X.* Italics
- X.de I
- X.it 1
- X$0 $1 $2 $3 $4 $5 $6 $7 $8 $9
- X.en
- X.* Bold
- X.de B
- X.bo 1
- X$0 $1 $2 $3 $4 $5 $6 $7 $8 $9
- X.en
- X.* Underline
- X.de U
- X.ul 1
- X$0 $1 $2 $3 $4 $5 $6 $7 $8 $9
- X.en
- X.* UC
- X.de UC
- X.* Empty
- X.en
- X.* Italics and Roman
- X.de IR
- X.if !''$0' .it "$0
- X.if !''$1' $1
- X.if !''$2' .it "$2
- X.if !''$3' $3
- X.if !''$4' .it "$4
- X.if !''$5' $5
- X.if !''$6' .it "$6
- X.if !''$7' $7
- X.if !''$8' .it "$8
- X.if !''$9' $9
- X.en
- X.* Roman and Italic
- X.de RI
- X.if !''$0' $0
- X.if !''$1' .it "$1
- X.if !''$2' $2
- X.if !''$3' .it "$3
- X.if !''$4' $4
- X.if !''$5' .it "$5
- X.if !''$6' $6
- X.if !''$7' .it "$7
- X.if !''$8' $8
- X.if !''$9' .it "$9
- X.en
- X.* Bold and Roman
- X.de BR
- X.if !''$0' .bo "$0
- X.if !''$1' $1
- X.if !''$2' .bo "$2
- X.if !''$3' $3
- X.if !''$4' .bo "$4
- X.if !''$5' $5
- X.if !''$6' .bo "$6
- X.if !''$7' $7
- X.if !''$8' .bo "$8
- X.if !''$9' $9
- X.en
- X.* Bold and Italic
- X.de BI
- X.if !''$0' .bo "$0
- X.if !''$1' .it "$1
- X.if !''$2' .bo "$2
- X.if !''$3' .it "$3
- X.if !''$4' .bo "$4
- X.if !''$5' .it "$5
- X.if !''$6' .bo "$6
- X.if !''$7' .it "$7
- X.if !''$8' .bo "$8
- X.if !''$9' .it "$9
- X.en
- X.* Italic and Bold
- X.de IB
- X.if !''$0' .it "$0
- X.if !''$1' .bo "$1
- X.if !''$2' .it "$2
- X.if !''$3' .bo "$3
- X.if !''$4' .it "$4
- X.if !''$5' .bo "$5
- X.if !''$6' .it "$6
- X.if !''$7' .bo "$7
- X.if !''$8' .it "$8
- X.if !''$9' .bo "$9
- X.en
- X.* Italic and Roman
- X.de IR
- X.if !''$0' .it "$0
- X.if !''$1' $1
- X.if !''$2' .it "$2
- X.if !''$3' $3
- X.if !''$4' .it "$4
- X.if !''$5' $5
- X.if !''$6' .it "$6
- X.if !''$7' $7
- X.if !''$8' .it "$8
- X.if !''$9' $9
- X.en
- X.* SMall, do nothing
- X.de SM
- X$0 $1 $2 $3 $4 $5 $6 $7 $8 $9
- X.en
- END_OF_FILE
- if test 2210 -ne `wc -c <'an'`; then
- echo shar: \"'an'\" unpacked with wrong size!
- fi
- # end of 'an'
- fi
- if test -f 'assign_macro.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'assign_macro.c'\"
- else
- echo shar: Extracting \"'assign_macro.c'\" \(1157 characters\)
- sed "s/^X//" >'assign_macro.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <string.h>
- X#include <ctype.h>
- X
- X/* 02/12/90 -- hu:
- X * New utility function for make to process a macro assignment string.
- X * Uses standard C string/ctype functions so it is not machine dependent.
- X * Called by input() and main().
- X*/
- Xvoid
- Xassign_macro (s)
- Xchar *s; /* s must be pre-checked for the presence of '=' */
- X{
- X char *name, *val;
- X register char *p, *q;
- X char svp, svq;
- X int use_empty = 0;
- X
- X /* bypass leading space */
- X while (isspace (*s)) s++;
- X name = s;
- X
- X /* find the = char */
- X p = strchr (s, '=');
- X if (p == name) return;
- X val = p + 1;
- X
- X if (*(p-1) == '\\') {
- X if ((p - 1) == name) return;
- X p--;
- X }
- X p--;
- X while (isspace(*p)) p--;
- X p++;
- X svp = *p;
- X *p = '\0';
- X
- X /* now check the value part, we just need to see if null string */
- X q = val;
- X while (*q != '\0' && isspace(*q)) q++;
- X if (*q == '\0') use_empty = 1;
- X else {
- X val = q;
- X q = val + strlen(val) - 1;
- X if (isspace(*q)) while (isspace(*q)) q--;
- X q++;
- X svq = *q;
- X *q = '\0';
- X }
- X
- X if (use_empty) setmacro (name, " ");
- X else setmacro (name, val);
- X
- X /* restore original chars that we replaced with null */
- X *p = svp;
- X if (use_empty == 0) *q = svq;
- X}
- END_OF_FILE
- if test 1157 -ne `wc -c <'assign_macro.c'`; then
- echo shar: \"'assign_macro.c'\" unpacked with wrong size!
- fi
- # end of 'assign_macro.c'
- fi
- if test -f 'check.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'check.c'\"
- else
- echo shar: Extracting \"'check.c'\" \(2152 characters\)
- sed "s/^X//" >'check.c' <<'END_OF_FILE'
- X/*
- X * Check structures for make.
- X */
- X
- X#include <stdio.h>
- X#include "h.h"
- X
- X
- X/*
- X * Prints out the structures as defined in memory. Good for check
- X * that you make file does what you want (and for debugging make).
- X */
- Xvoid
- Xprt()
- X{
- X register struct name *np;
- X register struct depend *dp;
- X register struct line *lp;
- X register struct cmd *cp;
- X register struct macro *mp;
- X
- X
- X for (mp = macrohead; mp; mp = mp->m_next)
- X fprintf(stderr, "%s = %s\n", mp->m_name, mp->m_val);
- X
- X fputc('\n', stderr);
- X
- X for (np = namehead.n_next; np; np = np->n_next) {
- X if (np->n_flag & N_DOUBLE)
- X fprintf(stderr, "%s::\n", np->n_name);
- X else
- X fprintf(stderr, "%s:\n", np->n_name);
- X if (np == firstname)
- X fprintf(stderr, "(MAIN NAME)\n");
- X for (lp = np->n_line; lp; lp = lp->l_next) {
- X fputc(':', stderr);
- X for (dp = lp->l_dep; dp; dp = dp->d_next)
- X fprintf(stderr, " %s", dp->d_name->n_name);
- X fputc('\n', stderr);
- X
- X for (cp = lp->l_cmd; cp; cp = cp->c_next)
- X#ifdef os9
- X fprintf(stderr, "- %s\n", cp->c_cmd);
- X#else
- X fprintf(stderr, "-\t%s\n", cp->c_cmd);
- X#endif
- X fputc('\n', stderr);
- X }
- X fputc('\n', stderr);
- X }
- X}
- X
- X
- X/*
- X * Recursive routine that does the actual checking.
- X */
- Xvoid
- Xcheck(np)
- X struct name *np;
- X{
- X register struct depend *dp;
- X register struct line *lp;
- X
- X
- X if (np->n_flag & N_MARK)
- X fatal("Circular dependency from %s", np->n_name);
- X
- X np->n_flag |= N_MARK;
- X
- X for (lp = np->n_line; lp; lp = lp->l_next)
- X for (dp = lp->l_dep; dp; dp = dp->d_next)
- X check(dp->d_name);
- X
- X np->n_flag &= ~N_MARK;
- X}
- X
- X
- X/*
- X * Look for circular dependancies.
- X * ie.
- X * a: b
- X * b: a
- X * is a circular dep
- X */
- Xvoid
- Xcirch()
- X{
- X register struct name *np;
- X
- X
- X for (np = namehead.n_next; np; np = np->n_next)
- X check(np);
- X}
- X
- X
- X/*
- X * Check the target .PRECIOUS, and mark its dependentd as precious
- X */
- Xvoid
- Xprecious()
- X{
- X register struct depend *dp;
- X register struct line *lp;
- X register struct name *np;
- X
- X
- X if (!((np = newname(".PRECIOUS"))->n_flag & N_TARG))
- X return;
- X
- X for (lp = np->n_line; lp; lp = lp->l_next)
- X for (dp = lp->l_dep; dp; dp = dp->d_next)
- X dp->d_name->n_flag |= N_PREC;
- X}
- END_OF_FILE
- if test 2152 -ne `wc -c <'check.c'`; then
- echo shar: \"'check.c'\" unpacked with wrong size!
- fi
- # end of 'check.c'
- fi
- if test -f 'h.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'h.h'\"
- else
- echo shar: Extracting \"'h.h'\" \(2546 characters\)
- sed "s/^X//" >'h.h' <<'END_OF_FILE'
- X/*
- X * Include header for make
- X */
- X
- X
- X#ifndef uchar
- X#ifdef os9
- X#define uchar char
- X#define void int
- X#define fputc putc
- X#else
- X#define uchar unsigned char
- X#endif
- X#endif
- X
- X#define bool uchar
- X#define time_t long
- X#define TRUE (1)
- X#define FALSE (0)
- X#define max(a,b) ((a)>(b)?(a):(b))
- X
- X#define DEFN1 "makefile" /* Default names */
- X#ifdef unix
- X#define DEFN2 "Makefile"
- X#endif
- X#ifdef eon
- X#define DEFN2 "Makefile"
- X#endif
- X
- X#ifdef amiga
- X#define strcmp stricmp
- X#endif
- X
- X/* os9 is case insensitive */
- X
- X#define LZ (1024) /* Line size */
- X
- X
- X
- X/*
- X * A name. This represents a file, either to be made, or existant
- X */
- X
- Xstruct name {
- X struct name *n_next; /* Next in the list of names */
- X char *n_name; /* Called */
- X struct line *n_line; /* Dependencies */
- X time_t n_time; /* Modify time of this name */
- X uchar n_flag; /* Info about the name */
- X};
- X
- X#define N_MARK 0x01 /* For cycle check */
- X#define N_DONE 0x02 /* Name looked at */
- X#define N_TARG 0x04 /* Name is a target */
- X#define N_PREC 0x08 /* Target is precious */
- X#define N_DOUBLE 0x10 /* Double colon target */
- X
- X/*
- X * Definition of a target line.
- X */
- Xstruct line {
- X struct line *l_next; /* Next line (for ::) */
- X struct depend *l_dep; /* Dependents for this line */
- X struct cmd *l_cmd; /* Commands for this line */
- X};
- X
- X
- X/*
- X * List of dependents for a line
- X */
- Xstruct depend {
- X struct depend *d_next; /* Next dependent */
- X struct name *d_name; /* Name of dependent */
- X};
- X
- X
- X/*
- X * Commands for a line
- X */
- Xstruct cmd {
- X struct cmd *c_next; /* Next command line */
- X char *c_cmd; /* Command line */
- X};
- X
- X
- X/*
- X * Macro storage
- X */
- Xstruct macro {
- X struct macro *m_next; /* Next variable */
- X char *m_name; /* Called ... */
- X char *m_val; /* Its value */
- X uchar m_flag; /* Infinite loop check */
- X};
- X
- Xextern char *myname;
- Xextern struct name namehead;
- Xextern struct macro *macrohead;
- Xextern struct name *firstname;
- Xextern bool silent;
- Xextern bool ignore;
- Xextern bool rules;
- Xextern bool dotouch;
- Xextern bool quest;
- Xextern bool domake;
- Xextern char str1[];
- Xextern char str2[];
- Xextern int lineno;
- X
- Xchar *fgets();
- Xchar *index();
- Xchar *rindex();
- Xchar *malloc();
- Xextern int errno;
- X
- Xchar *getmacro();
- Xstruct macro *setmacro();
- Xvoid input();
- Xvoid error();
- Xvoid fatal();
- Xint make();
- Xstruct name *newname();
- Xstruct depend *newdep();
- Xstruct cmd *newcmd();
- Xvoid newline();
- Xchar *suffix();
- Xvoid touch();
- Xvoid makerules();
- Xchar *gettok();
- Xvoid precious();
- END_OF_FILE
- if test 2546 -ne `wc -c <'h.h'`; then
- echo shar: \"'h.h'\" unpacked with wrong size!
- fi
- # end of 'h.h'
- fi
- if test -f 'input.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'input.c'\"
- else
- echo shar: Extracting \"'input.c'\" \(7073 characters\)
- sed "s/^X//" >'input.c' <<'END_OF_FILE'
- X/*
- X * Parse a makefile
- X */
- X
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "h.h"
- X
- X
- Xstruct name namehead;
- Xstruct name *firstname;
- X
- Xchar str1[LZ]; /* General store */
- Xchar str2[LZ];
- X
- X
- X/*
- X * Intern a name. Return a pointer to the name struct
- X */
- Xstruct name *
- Xnewname(name)
- X char *name;
- X{
- X register struct name *rp;
- X register struct name *rrp;
- X register char *cp;
- X
- X
- X for
- X (
- X rp = namehead.n_next, rrp = &namehead;
- X rp;
- X rp = rp->n_next, rrp = rrp->n_next
- X )
- X if (strcmp(name, rp->n_name) == 0)
- X return rp;
- X
- X if ((rp = (struct name *) malloc(sizeof(struct name)))
- X == (struct name *) 0)
- X fatal("No memory for name");
- X rrp->n_next = rp;
- X rp->n_next = (struct name *) 0;
- X if ((cp = malloc((unsigned) strlen(name) + 1)) == (char *) 0)
- X fatal("No memory for name");
- X strcpy(cp, name);
- X rp->n_name = cp;
- X rp->n_line = (struct line *) 0;
- X rp->n_time = (time_t) 0;
- X rp->n_flag = 0;
- X
- X return rp;
- X}
- X
- X/*
- X * Delete the last created name.
- X */
- X
- Xdelname(np)
- Xstruct name *np;
- X{
- X if (namehead.n_next == np) {
- X namehead.n_next = np->n_next;
- X free(np);
- X }
- X}
- X
- X/*
- X * Add a dependant to the end of the supplied list of dependants.
- X * Return the new head pointer for that list.
- X */
- Xstruct depend *
- Xnewdep(np, dp)
- X struct name *np;
- X struct depend *dp;
- X{
- X register struct depend *rp;
- X register struct depend *rrp;
- X
- X
- X if ((rp = (struct depend *) malloc(sizeof(struct depend)))
- X == (struct depend *) 0)
- X fatal("No memory for dependant");
- X rp->d_next = (struct depend *) 0;
- X rp->d_name = np;
- X
- X if (dp == (struct depend *) 0)
- X return rp;
- X
- X for (rrp = dp; rrp->d_next; rrp = rrp->d_next);
- X
- X rrp->d_next = rp;
- X
- X return dp;
- X}
- X
- X
- X/*
- X * Add a command to the end of the supplied list of commands.
- X * Return the new head pointer for that list.
- X */
- Xstruct cmd *
- Xnewcmd(str, cp)
- X char *str;
- X struct cmd *cp;
- X{
- X register struct cmd *rp;
- X register struct cmd *rrp;
- X register char *rcp;
- X
- X
- X if (rcp = rindex(str, '\n'))
- X *rcp = '\0'; /* Loose newline */
- X
- X while (isspace(*str))
- X str++;
- X
- X if (*str == '\0') /* If nothing left, the exit */
- X return (struct cmd *) 0;
- X
- X if ((rp = (struct cmd *) malloc(sizeof(struct cmd)))
- X == (struct cmd *) 0)
- X fatal("No memory for command");
- X rp->c_next = (struct cmd *) 0;
- X if ((rcp = malloc((unsigned) strlen(str) + 1)) == (char *) 0)
- X fatal("No memory for command");
- X strcpy(rcp, str);
- X rp->c_cmd = rcp;
- X
- X if (cp == (struct cmd *) 0)
- X return rp;
- X
- X for (rrp = cp; rrp->c_next; rrp = rrp->c_next);
- X
- X rrp->c_next = rp;
- X
- X return cp;
- X}
- X
- X
- X/*
- X * Add a new 'line' of stuff to a target. This check to see
- X * if commands already exist for the target. If flag is set,
- X * the line is a double colon target.
- X *
- X * Kludges:
- X * i) If the new name begins with a '.', and there are no dependents,
- X * then the target must cease to be a target. This is for .SUFFIXES.
- X * ii) If the new name begins with a '.', with no dependents and has
- X * commands, then replace the current commands. This is for
- X * redefining commands for a default rule.
- X * Neither of these free the space used by dependents or commands,
- X * since they could be used by another target.
- X */
- Xvoid
- Xnewline(np, dp, cp, flag)
- X struct name *np;
- X struct depend *dp;
- X struct cmd *cp;
- X bool flag;
- X{
- X bool hascmds = FALSE; /* Target has commands */
- X register struct line *rp;
- X register struct line *rrp;
- X
- X
- X /* Handle the .SUFFIXES case */
- X if (np->n_name[0] == '.' && !dp && !cp) {
- X for (rp = np->n_line; rp; rp = rrp) {
- X rrp = rp->l_next;
- X free((char *) rp);
- X }
- X np->n_line = (struct line *) 0;
- X np->n_flag &= ~N_TARG;
- X return;
- X }
- X /* This loop must happen since rrp is used later. */
- X for
- X (
- X rp = np->n_line, rrp = (struct line *) 0;
- X rp;
- X rrp = rp, rp = rp->l_next
- X )
- X if (rp->l_cmd)
- X hascmds = TRUE;
- X
- X if (hascmds && cp && !(np->n_flag & N_DOUBLE))
- X /* Handle the implicit rules redefinition case */
- X if (np->n_name[0] == '.' && dp == (struct depend *) 0) {
- X np->n_line->l_cmd = cp;
- X return;
- X } else
- X error("Commands defined twice for target %s", np->n_name);
- X if (np->n_flag & N_TARG)
- X if (!(np->n_flag & N_DOUBLE) != !flag) /* like xor */
- X error("Inconsistent rules for target %s", np->n_name);
- X
- X if ((rp = (struct line *) malloc(sizeof(struct line)))
- X == (struct line *) 0)
- X fatal("No memory for line");
- X rp->l_next = (struct line *) 0;
- X rp->l_dep = dp;
- X rp->l_cmd = cp;
- X
- X if (rrp)
- X rrp->l_next = rp;
- X else
- X np->n_line = rp;
- X
- X np->n_flag |= N_TARG;
- X if (flag)
- X np->n_flag |= N_DOUBLE;
- X}
- X
- X
- X/*
- X * Parse input from the makefile, and construct a tree structure
- X * of it.
- X */
- Xvoid
- Xinput(fd)
- X FILE *fd;
- X{
- X char *p; /* General */
- X char *q;
- X struct name *np;
- X struct depend *dp;
- X struct cmd *cp;
- X bool dbl, getline();
- X
- X
- X if (getline(str1, LZ, fd)) /* Read the first line */
- X return;
- X
- X for (;;) {
- X if (str1[0] == '\t' || str1[0] == ' ') /* Rules without targets */
- X error("Rules not allowed here");
- X
- X p = str1;
- X
- X while (isspace(*p)) /* Find first target */
- X p++;
- X
- X /* -- hu: if = exists in string, hand the string to assign_macro() */
- X if ((q = index(p, '=')) != NULL) {
- X assign_macro (p);
- X if (getline(str1, LZ, fd)) return;
- X continue;
- X }
- X
- X expand(str1);
- X p = str1;
- X#if 0
- X while (((q = index(p, ':')) != (char *) 0) &&
- X (p != q) && (q[-1] == '\\')) { /* Find dependents */
- X register char *a;
- X
- X a = q - 1; /* Del \ chr; move rest back */
- X p = q;
- X while (*a++ = *q++);
- X }
- X#else
- X q = index(p, ':');
- X#endif
- X
- X if (q == (char *) 0)
- X error("No targets provided");
- X
- X /* Added by OIS to allow at most one : in target names */
- X
- X {
- X register char *a = q;
- X
- X while (*++a) {
- X if (*a == ' ' || *a == '\t') {
- X /* Found no more colons. Must have been first one. */
- X break;
- X }
- X if (*a == ':') {
- X /* Found second colon. This must be the separator. */
- X if (a != q+1) /* No double colon */
- X q = a;
- X break;
- X }
- X }
- X }
- X
- X *q++ = '\0'; /* Separate targets and dependents */
- X
- X if (*q == ':') { /* Double colon */
- X dbl = 1;
- X q++;
- X } else
- X dbl = 0;
- X
- X for (dp = (struct depend *) 0; ((p = gettok(&q)) != (char *) 0);)
- X /* get list of dep's */
- X {
- X np = newname(p); /* Intern name */
- X dp = newdep(np, dp);/* Add to dep list */
- X }
- X
- X *((q = str1) + strlen(str1) + 1) = '\0';
- X /* Need two nulls for gettok (Remember separation) */
- X
- X cp = (struct cmd *) 0;
- X if (getline(str2, LZ, fd) == FALSE) { /* Get commands */
- X while (str2[0] == '\t' || str2[0] == ' ') { /*OIS*0.80*/
- X cp = newcmd(&str2[0], cp);
- X if (getline(str2, LZ, fd))
- X break;
- X }
- X }
- X while ((p = gettok(&q)) != (char *) 0) { /* Get list of targ's */
- X np = newname(p); /* Intern name */
- X newline(np, dp, cp, dbl);
- X if (!firstname && p[0] != '.')
- X firstname = np;
- X }
- X
- X if (feof(fd)) /* EOF? */
- X return;
- X
- X strcpy(str1, str2);
- X }
- X}
- END_OF_FILE
- if test 7073 -ne `wc -c <'input.c'`; then
- echo shar: \"'input.c'\" unpacked with wrong size!
- fi
- # end of 'input.c'
- fi
- if test -f 'macro.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'macro.c'\"
- else
- echo shar: Extracting \"'macro.c'\" \(2582 characters\)
- sed "s/^X//" >'macro.c' <<'END_OF_FILE'
- X/*
- X * Macro control for make
- X */
- X
- X
- X#include "h.h"
- X#undef strcmp /*OIS*0.80*/
- X
- Xstruct macro *macrohead;
- X
- X
- Xstruct macro *
- Xgetmp(name)
- X register char *name;
- X{
- X register struct macro *rp;
- X
- X for (rp = macrohead; rp; rp = rp->m_next)
- X if (strcmp(name, rp->m_name) == 0)
- X return rp;
- X return (struct macro *) 0;
- X}
- X
- X
- Xchar *
- Xgetmacro(name)
- X char *name;
- X{
- X struct macro *mp;
- X
- X if (mp = getmp(name))
- X return mp->m_val;
- X else
- X return "";
- X}
- X
- X
- Xstruct macro *
- Xsetmacro(name, val)
- X char *name;
- X char *val;
- X{
- X register struct macro *rp;
- X register char *cp;
- X
- X
- X /* Replace macro definition if it exists */
- X for (rp = macrohead; rp; rp = rp->m_next)
- X if (strcmp(name, rp->m_name) == 0) {
- X free(rp->m_val); /* Free space from old */
- X break;
- X }
- X if (!rp) { /* If not defined, allocate space for new */
- X if ((rp = (struct macro *) malloc(sizeof(struct macro)))
- X == (struct macro *) 0)
- X fatal("No memory for macro");
- X
- X rp->m_next = macrohead;
- X macrohead = rp;
- X rp->m_flag = FALSE;
- X
- X if ((cp = malloc((unsigned) strlen(name) + 1)) == (char *) 0)
- X fatal("No memory for macro");
- X strcpy(cp, name);
- X rp->m_name = cp;
- X }
- X if ((cp = malloc((unsigned) strlen(val) + 1)) == (char *) 0)
- X fatal("No memory for macro");
- X strcpy(cp, val); /* Copy in new value */
- X rp->m_val = cp;
- X
- X return rp;
- X}
- X
- X
- X/*
- X * Do the dirty work for expand
- X */
- Xvoid
- Xdoexp(to, from, len, buf)
- X char **to;
- X char *from;
- X int *len;
- X char *buf;
- X{
- X register char *rp;
- X register char *p;
- X register char *q;
- X register struct macro *mp;
- X
- X
- X rp = from;
- X p = *to;
- X while (*rp) {
- X if (*rp != '$') {
- X *p++ = *rp++;
- X (*len)--;
- X } else {
- X q = buf;
- X if (*++rp == '{')
- X while (*++rp && *rp != '}')
- X *q++ = *rp;
- X else if (*rp == '(')
- X while (*++rp && *rp != ')')
- X *q++ = *rp;
- X else if (!*rp) {
- X *p++ = '$';
- X break;
- X } else
- X *q++ = *rp;
- X *q = '\0';
- X if (*rp)
- X rp++;
- X if (!(mp = getmp(buf)))
- X mp = setmacro(buf, "");
- X if (mp->m_flag)
- X fatal("Infinitely recursive macro %s", mp->m_name);
- X mp->m_flag = TRUE;
- X *to = p;
- X doexp(to, mp->m_val, len, buf);
- X p = *to;
- X mp->m_flag = FALSE;
- X }
- X if (*len <= 0)
- X error("Expanded line too long"); /*OIS*0.80*/
- X }
- X *p = '\0';
- X *to = p;
- X}
- X
- X
- X/*
- X * Expand any macros in str.
- X */
- Xvoid
- Xexpand(str)
- X char *str;
- X{
- X static char a[LZ];
- X static char b[LZ];
- X char *p = str;
- X int len = LZ - 1;
- X
- X strcpy(a, str);
- X doexp(&p, a, &len, b);
- X}
- END_OF_FILE
- if test 2582 -ne `wc -c <'macro.c'`; then
- echo shar: \"'macro.c'\" unpacked with wrong size!
- fi
- # end of 'macro.c'
- fi
- if test -f 'main.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'main.c'\"
- else
- echo shar: Extracting \"'main.c'\" \(6566 characters\)
- sed "s/^X//" >'main.c' <<'END_OF_FILE'
- X/*
- X * make [-f makefile] [-ins] [target(s) ...]
- X *
- X * (Better than EON mk but not quite as good as UNIX make)
- X *
- X * -f makefile name
- X * -i ignore exit status
- X * -n Pretend to make
- X * -p Print all macros & targets
- X * -q Question up-to-dateness of target. Return exit status 1 if not
- X * -r Don't not use inbuilt rules
- X * -s Make silently
- X * -t Touch files instead of making them
- X * -m Change memory requirements (EON only)
- X */
- X
- X#include <stdio.h>
- X#include "h.h"
- X
- X#ifdef unix
- X#include <sys/errno.h>
- X#endif
- X#ifdef eon
- X#include <sys/err.h>
- X#endif
- X#ifdef os9
- X#include <errno.h>
- X#endif
- X#ifdef amiga
- X#include <errno.h>
- X#endif
- X
- X#ifdef eon
- X#define MEMSPACE (16384)
- X#endif
- X
- X
- Xchar *myname;
- Xchar *makefile; /* The make file */
- X#ifdef eon
- Xunsigned memspace = MEMSPACE;
- X#endif
- X
- XFILE *ifd; /* Input file desciptor */
- Xbool domake = TRUE; /* Go through the motions option */
- Xbool ignore = FALSE; /* Ignore exit status option */
- Xbool silent = FALSE; /* Silent option */
- Xbool print = FALSE; /* Print debuging information */
- Xbool rules = TRUE; /* Use inbuilt rules */
- Xbool dotouch = FALSE;/* Touch files instead of making */
- Xbool quest = FALSE; /* Question up-to-dateness of file */
- X
- X
- Xvoid
- Xmain(argc, argv)
- X register int argc;
- X register char **argv;
- X{
- X register char *p; /* For argument processing */
- X int estat = 0; /* For question */
- X register struct name *np;
- X void prt(), circh();
- X
- X myname = (argc-- < 1) ? "make" : *argv++;
- X
- X while ((argc > 0) && (**argv == '-')) {
- X argc--; /* One less to process */
- X p = *argv++; /* Now processing this one */
- X
- X while (*++p != '\0') {
- X switch (*p) {
- X case 'f': /* Alternate file name */
- X if (*++p == '\0') {
- X if (argc-- <= 0)
- X usage();
- X p = *argv++;
- X }
- X makefile = p;
- X goto end_of_args;
- X#ifdef eon
- X case 'm': /* Change space requirements */
- X if (*++p == '\0') {
- X if (argc-- <= 0)
- X usage();
- X p = *argv++;
- X }
- X memspace = atoi(p);
- X goto end_of_args;
- X#endif
- X case 'n': /* Pretend mode */
- X domake = FALSE;
- X break;
- X case 'i': /* Ignore fault mode */
- X ignore = TRUE;
- X break;
- X case 's': /* Silent about commands */
- X silent = TRUE;
- X break;
- X case 'p':
- X print = TRUE;
- X break;
- X case 'r':
- X rules = FALSE;
- X break;
- X case 't':
- X dotouch = TRUE;
- X break;
- X case 'q':
- X quest = TRUE;
- X break;
- X default: /* Wrong option */
- X usage();
- X }
- X }
- Xend_of_args:;
- X }
- X
- X#ifdef amiga
- X if ((ifd = fopen("s:builtins.make", "r")) != (FILE *) 0) {
- X input(ifd);
- X fclose(ifd);
- X } else
- X#endif
- X makerules();
- X
- X#ifdef eon
- X if (initalloc(memspace) == 0xffff) /* Must get memory for alloc */
- X fatal("Cannot initalloc memory");
- X#endif
- X
- X if (! makefile) { /* If no file, then use default */
- X if ((ifd = fopen(DEFN1, "r")) == (FILE *) 0)
- X#ifdef eon
- X if (errno != ER_NOTF)
- X fatal("Can't open %s; error %02x", DEFN1, errno);
- X#endif
- X#ifdef unix
- X if (errno != ENOENT)
- X fatal("Can't open %s; error %02x", DEFN1, errno);
- X#endif
- X#ifdef amiga
- X if (errno != ENOENT)
- X fatal("Can't open %s; error %02x", DEFN1, errno);
- X#endif
- X#ifdef DEFN2
- X if ((ifd == (FILE *) 0)
- X && ((ifd = fopen(DEFN2, "r")) == (FILE *) 0))
- X fatal("Can't open %s", DEFN2);
- X#else
- X /* -- hu: do nothing so we may process command line later */
- X#endif
- X } else if (strcmp(makefile, "-") == 0) /* Can use stdin as makefile */
- X ifd = stdin;
- X else if ((ifd = fopen(makefile, "r")) == (FILE *) 0)
- X ; /* -- hu: again, no makefile is fine here */
- X
- X /* -- hu: if valid makefile exists, read it in now */
- X if (ifd != (FILE *)0) {
- X input(ifd); /* Input all the gunga */
- X fclose(ifd); /* Finished with makefile */
- X }
- X lineno = 0; /* Any calls to error now print no line
- X * number */
- X
- X setmacro ("$", "$");
- X
- X /* -- hu: overwrite/add command line macro assignments */
- X while (argc && (p = index(*argv, '='))) {
- X assign_macro(*argv);
- X argv++;
- X argc--;
- X }
- X
- X if (print)
- X prt(); /* Print out structures */
- X
- X np = newname(".SILENT");
- X if (np->n_flag & N_TARG)
- X silent = TRUE;
- X
- X np = newname(".IGNORE");
- X if (np->n_flag & N_TARG)
- X ignore = TRUE;
- X
- X precious();
- X
- X /* Check circles in target definitions */
- X if (! firstname) circh();
- X
- X /* -- hu: no command line arg, if target defined from makefile, do it */
- X if (argc == 0) {
- X if (! firstname) estat = make(firstname, 0);
- X }
- X else /* treat command line args as targets to make */
- X while (argc--) {
- X if (!print && !silent && strcmp(*argv, "love") == 0) {
- X if (strcmp(myname, "make") == 0) /* -- hu: humor them */
- X printf("With me?\n");
- X else printf("Not War!\n");
- X }
- X else estat |= make(newname(*argv++), 0);
- X }
- X
- X if (quest) exit (estat);
- X else exit (0);
- X}
- X
- X
- Xusage()
- X{
- X fprintf(stderr,
- X"Usage: %s [-f makefile] [-inpqrst] [macro=val ...] [target(s) ...]\n", myname);
- X fprintf(stderr,"\n");
- X fprintf(stderr," -f file Use `file' instead of `M/makefile'\n");
- X fprintf(stderr," -i Ignore invoked command errors (continue regardless)\n");
- X fprintf(stderr," -n No make (just print actions to be taken)\n");
- X fprintf(stderr," -p Print all macros & targets\n");
- X fprintf(stderr," -q Check if target is up-to-date. Exit 1 if not\n");
- X fprintf(stderr," -r Don't use built-in rules\n");
- X fprintf(stderr," -s Make silently\n");
- X fprintf(stderr," -t Touch needed files instead of making them\n");
- X#ifdef eon
- X fprintf(stderr," -m Change memory requirements (EON only)\n");
- X#endif
- X exit(1);
- X}
- X
- X
- Xvoid
- Xfatal(msg, a1, a2, a3, a4, a5, a6)
- X char *msg;
- X{
- X fprintf(stderr, "%s: ", myname);
- X fprintf(stderr, msg, a1, a2, a3, a4, a5, a6);
- X fputc('\n', stderr);
- X exit(1);
- X}
- X
- X#ifdef amiga /*OIS*0.80*/
- X
- X/*
- X * The Amiga case-insensitive filing system needs a case-insensitive
- X * filename comparison. Since strcmp() in this make is only applied to
- X * filenames, we simply replace it.
- X * Unfortunately, this also affects .PRECIOUS, .IGNORE, .SUFFIXES and
- X * .SILENT. Therefore, we need a hack, but that costs space, so we don't.
- X */
- X
- Xint lower(c)
- Xregister unsigned int c;
- X{
- X if (c >= 'A' && c <= 'Z')
- X return c - 'A' + 'a';
- X
- X return c;
- X}
- X
- Xint stricmp(first, second) /* Case-insensitive strcmp() */
- Xregister unsigned char *first, *second;
- X{
- X register int cmp;
- X
- X while (!(cmp = lower(*first++) - lower(*second++))) {
- X if (!first[-1]) return 0;
- X }
- X
- X return (cmp < 0) ? -1 : 1;
- X}
- X
- X/* Manx and PDC allow you to leave out Workbench code */
- X
- X_wb_parse(){}
- X
- X#endif
- END_OF_FILE
- if test 6566 -ne `wc -c <'main.c'`; then
- echo shar: \"'main.c'\" unpacked with wrong size!
- fi
- # end of 'main.c'
- fi
- if test -f 'make.n' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'make.n'\"
- else
- echo shar: Extracting \"'make.n'\" \(7344 characters\)
- sed "s/^X//" >'make.n' <<'END_OF_FILE'
- X.so an
- X.de HP
- X.ti -5
- X.en
- X.TH MAKE 1 "AMIGA Programmer's Manual"
- X.SH NAME
- Xmake - maintain program groups
- X.SH SYNTAX
- Xmake [ -f makefile ] [ option ] ... file ...
- X.SH DESCRIPTION
- X.I Make
- Xexecutes commands in
- X.I makefile
- Xto update one or more target
- X.I names. Name
- Xis typically a program. If no -f option
- Xis present, `makefile' and `Makefile' are tried in order.
- XIf
- X.I makefile
- Xis `-', the standard input is taken. More than one -f option may appear.
- X
- X.I Make
- Xupdates a target if it depends on prerequisite files that have been
- Xmodified since the target was last modified, or if the target does not
- Xexist.
- X
- X.I Makefile
- Xcontains a sequence of entries that specify dependencies. The first line of
- Xan entry is a blank-separated list of targets, then a colon, then a list of
- Xprerequisite files. Text following a semicolon, and all following lines
- Xthat begin with a tab, are shell commands to be executed to update the
- Xtarget. If a name appears on the left of more than one `colon' line, then
- Xit depends on all of the names on the right of the colon on those lines,
- Xbut only one command sequence may be specified for it. If a name appears on
- Xa line with a double colon :: then the command sequence following that line
- Xis performed only if the name is out of date with respect to the names to
- Xthe right of the double colon, and is not affected by other double colon
- Xlines on which that name may appear.
- X
- XTwo special forms of a name are recognized. A name like
- X.I a(b)
- Xmeans the file named
- X.I b
- Xstored in the archive named
- X.I a.
- XA name like
- X.I a((b))
- Xmeans the file stored in archive a containing the entry point
- X.I b.
- X
- XSharp and newline surround comments.
- X
- XThe following makefile says that `pgm' depends on two files `a.o' and
- X`b.o', and that they in turn depend on `.c' files and a common file `incl'.
- X
- X pgm: a.o b.o
- X cc a.o b.o -lm -o pgm
- X a.o: incl a.c
- X cc -c a.c
- X b.o: incl b.c
- X cc -c b.c
- X
- X.I Makefile
- Xentries of the form
- X
- X string1 = string2
- X
- Xare macro definitions. Subsequent appearances of
- X.I $(string1)
- Xor
- X.I ${string1}
- Xare replaced by
- X.I string2.
- XIf
- X.I string1
- Xis a single character, the parentheses or braces are optional.
- X
- X.I Make
- Xinfers prerequisites for files for which
- X.I makefile
- Xgives no construction commands. For example, a `.c' file may be inferred as
- Xprerequisite for a `.o' file and be compiled to produce the `.o' file. Thus
- Xthe preceding example can be done more briefly:
- X
- X pgm: a.o b.o
- X cc a.o b.o -lm -o pgm
- X a.o b.o: incl
- X
- XPrerequisites are inferred according to selected suffixes listed as the
- X`prerequisites' for the special name `.SUFFIXES'; multiple lists
- Xaccumulate; an empty list clears what came before. Order is significant;
- Xthe first possible name for which both a file and a rule as described in
- Xthe next paragraph exist is inferred. The default list is
- X
- X .SUFFIXES: .out .o .c .e .r .f .y .l .s .p
- X
- XThe rule to create a file with suffix
- X.I s2
- Xthat depends on a similarly named file with suffix
- X.I s1
- Xis specified as an entry for the `target'
- X.I s1s2.
- XIn such an entry, the special macro $* stands for the target name with
- Xsuffix deleted, $@@ for the full target name, $< for the complete list of
- Xprerequisites, and $? for the list of prerequisites that are out of date.
- XFor example, a rule for making optimized `.o' files from `.c' files is
- X
- X .c.o: ; cc -c -O -o $@@ $*.c
- X
- XCertain macros are used by the default inference rules to communicate
- Xoptional arguments to any resulting compilations. In particular, `CFLAGS'
- Xis used for
- X.I cc(1)
- Xoptions, `FFLAGS' for
- X.I f77(1)
- Xoptions, `PFLAGS' for
- X.I pc(1)
- Xoptions, and `LFLAGS' and `YFLAGS' for
- X.I lex
- Xand
- X.I yacc(1)
- Xoptions. In addition, the macro `MFLAGS' is filled in with the initial
- Xcommand line options supplied to
- X.I make.
- XThis simplifies maintaining a hierarchy of makefiles as one may then invoke
- X.I make
- Xon makefiles in subdirectories and pass along useful options such as -k.
- X
- XCommand lines are executed one at a time, each by its own shell. A line is
- Xprinted when it is executed unless the special target `.SILENT' is in
- X.I makefile,
- Xor the first character of the command is `@@'.
- X
- XCommands returning nonzero status (see
- X.I intro(1))
- Xcause
- X.I make
- Xto terminate unless the special target `.IGNORE' is in
- X.I makefile
- Xor the command begins with <tab><hyphen>.
- X
- XInterrupt and quit cause the target to be deleted unless the target is a
- Xdirectory or depends on the special name `.PRECIOUS'.
- X
- XOther options:
- X
- X.RS +5
- X.HP
- X-i@tEquivalent to the special entry `.IGNORE:'.
- X
- X.HP
- X-k@tWhen a command returns nonzero status, abandon work on the current
- Xentry, but continue on branches that do not depend on the current entry.
- X
- X.HP
- X-n@tTrace and print, but do not execute the commands needed to update the
- Xtargets.
- X
- X.HP
- X-t@tTouch, i.e. update the modified date of targets, without executing any
- Xcommands.
- X
- X.HP
- X-r@tEquivalent to an initial special entry `.SUFFIXES:' with no list.
- X
- X.HP
- X-s@tEquivalent to the special entry `.SILENT:'.
- X
- X.HP
- X-q@tQuestion up-to-dateness of target. Return exit status 1 if not;
- Xotherwise, return 0.
- X
- X.HP
- X-r@tDon't use built-in rules.
- X.RE
- X.SH FILES
- Xmakefile, Makefile
- X.SH "SEE ALSO"
- Xsh(1), touch(1), f77(1), pc(1)
- X.br
- XS. I. Feldman
- X.I "Make - A Program for Maintaining Computer Programs"
- X.SH BUGS
- XSome commands return nonzero status inappropriately. Use -i
- Xto overcome the difficulty.
- XCommands that are directly executed by the shell, notably
- X.I cd(1),
- Xare ineffectual across newlines in
- X.I make.
- X.SH "AMIGA VERSION"
- XNot all of the above applies to the Amiga version of
- X.I make.
- XIn particular, the default rules and suffixes are different.
- X
- XOmissions:
- X.br
- XLibraries and the related notation are not implemented.
- X.br
- XThe -k option is not supported.
- X.br
- XThe `;' construct is not implemented.
- X.br
- XThe remarks related to
- X.I MFLAGS, lex(1), yacc(1), f77(1)
- Xand
- X.I pc(1)
- Xdo not apply.
- X.br
- X$< and $? are not exactly as specified: $< is ONE prerequisite that is out
- Xof date (including path name), and $? is ALL prerequisites (without path
- Xnames).
- X
- XAdditions:
- X.br
- XIf a file
- X.I s:builtins.make
- Xexists, this file is used instead of the built-in rules.
- X.br
- XFilenames are not case-significant. Unfortunately, this also applies to the
- Xspecial target names .PRECIOUS, .IGNORE and .SILENT. These can also be
- Xspecified as .Precious, or .iGnOrE.
- X.br
- X.I Cd
- Xcommands are effective.
- X.br
- XComment characters (#) may be escaped with a backslash (\).
- X.br
- XAt most 1 colon is allowed in a target file name (for including device
- Xnames). In that case, the trailing colon must follow the target name
- Ximmediately, without any intervening white space. Spaces in the names are
- Xnot allowed.
- X.br
- XA new special target name has been added:
- X.it "@.PATH.
- XAny prerequisite names for
- X.it "@.PATH
- Xare used for finding source files for implicit rules. You name one or more
- Xdirectories, and if the source file for an implicit rule cannot be found
- Xin the current directory, each of the the given pathnames is prepended (in
- Xthe order given) to the source name, until the file is found.
- X
- XFor instance, the Makefile
- X
- X .PATH: src/ include/ src/old
- X
- X pgm: pgm.o
- X
- Xwill look (according to the .c.o rule) for pgm.c, src/pgm.c, include/pgm.c
- Xand src/oldpgm.c, in that order. Of course, due to other implicit rules,
- Xother files (with other suffixes) may be tried as well.
- END_OF_FILE
- if test 7344 -ne `wc -c <'make.n'`; then
- echo shar: \"'make.n'\" unpacked with wrong size!
- fi
- # end of 'make.n'
- fi
- if test -f 'makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'makefile'\"
- else
- echo shar: Extracting \"'makefile'\" \(580 characters\)
- sed "s/^X//" >'makefile' <<'END_OF_FILE'
- X# Makefile for PDmake (to use MANX 3.6a compiler/linker)
- X#
- X# +L so integers are 32-bit long.
- X#
- X# (I wish people who release makefiles will pick this up as a habit: note
- X# what your various option flags mean, so that those who don't use the same
- X# compiler as you can still understand what is happening. -huver)
- X
- XCFLAGS=+L -Damiga -Dmanx #-Dpdc
- XCC=cc
- X
- XOBJS = main.o make.o rules.o reader.o \
- X # comment embeded in continuation
- X input.o macro.o assign_macro.o check.o
- X
- Xm: $(OBJS)
- X ln -o m $(OBJS) -lc
- X
- Xclean: $(OBJS)
- X delete $(OBJS)
- X
- Xman: make.n an
- X nro >make.man make.n
- END_OF_FILE
- if test 580 -ne `wc -c <'makefile'`; then
- echo shar: \"'makefile'\" unpacked with wrong size!
- fi
- # end of 'makefile'
- fi
- if test -f 'reader.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'reader.c'\"
- else
- echo shar: Extracting \"'reader.c'\" \(2516 characters\)
- sed "s/^X//" >'reader.c' <<'END_OF_FILE'
- X/*
- X * Read in makefile
- X */
- X
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "h.h"
- X
- X
- Xint lineno;
- X
- X
- X/*
- X * Syntax error handler. Print message, with line number, and exits.
- X */
- Xvoid
- Xerror(msg, a1, a2, a3)
- X char *msg;
- X{
- X fprintf(stderr, "%s: ", myname);
- X fprintf(stderr, msg, a1, a2, a3);
- X if (lineno)
- X fprintf(stderr, " near line %d", lineno);
- X fputc('\n', stderr);
- X exit(1);
- X}
- X
- X
- X/*
- X * Read a line into the supplied buffer of length 'size'. Remove
- X * comments, ignore blank lines. Deal with quoted (\) #, and
- X * quoted newlines. If EOF return TRUE.
- X *
- X * -hu: "Deal with quoted #"? What the bloody heck is that? '#' is a
- X * comment introducer, from it to end-of-line should be ignored.
- X */
- Xbool
- Xgetline (str, size, fd)
- Xchar *str;
- Xint size;
- XFILE *fd;
- X{
- X register char *p;
- X register char *q; /*OIS*0.80*/
- X register char *buf;
- X int pos = 0;
- X
- X size--; /* disccount one byte for null terminator */
- X
- X for (;;) {
- X
- X if ((size - pos) <= 0) error ("Line too long");
- X buf = str + pos;
- X if (fgets(buf, size - pos, fd) == NULL)
- X return TRUE; /* EOF */
- X
- X lineno++;
- X if ((p = index(buf, '\n')) == NULL) error("Line too long");
- X
- X /* strip out comment */
- X if ((p = index(buf, '#')) != NULL) {
- X if (p == buf) continue;
- X *p = '\0';
- X }
- X
- X /* empty line ? */
- X for (p = buf; isspace(*p); p++);
- X if (*p == '\0') continue;
- X
- X /* compress leading spaces from continued line(s) */
- X if (pos && p != buf)
- X for (q = buf; (*q = *p) != '\0'; q++, p++);
- X
- X /* look at last char */
- X p = buf + strlen(buf) - 1;
- X
- X /* skip trailing white spaces -- we know now the line isn't empty */
- X while ( isspace (*p)) p--;
- X
- X /* backslash continuation? */
- X if (*p == '\\') {
- X /* compress whitespaces before \ char */
- X p--;
- X while (isspace(*p)) p--;
- X *++p = ' '; /* replace with single space */
- X pos = (++p) - str; /* go read more */
- X continue;
- X }
- X *++p = '\n';
- X return FALSE; /* a valid line is read in */
- X }
- X}
- X
- X
- X/*
- X * Get a word from the current line, surounded by white space.
- X * return a pointer to it. String returned has no white spaces
- X * in it.
- X */
- Xchar *
- Xgettok(ptr)
- X register char **ptr; /*OIS*0.80*/
- X{
- X register char *p;
- X
- X
- X while (isspace(**ptr)) /* Skip spaces */
- X (*ptr)++;
- X
- X if (**ptr == '\0') /* Nothing after spaces */
- X return NULL;
- X
- X p = *ptr; /* word starts here */
- X
- X while ((**ptr != '\0') && (!isspace(**ptr)))
- X (*ptr)++; /* Find end of word */
- X
- X *(*ptr)++ = '\0'; /* Terminate it */
- X
- X return (p);
- X}
- END_OF_FILE
- if test 2516 -ne `wc -c <'reader.c'`; then
- echo shar: \"'reader.c'\" unpacked with wrong size!
- fi
- # end of 'reader.c'
- fi
- echo shar: End of archive 1 \(of 2\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
- Mail comments to the moderator at <amiga-request@cs.odu.edu>.
- Post requests for sources, and general discussion to comp.sys.amiga.
-